﻿using Sustainalytics.Synchronization.Interface;
using Sustainalytics.Entities;
using Sustainalytics.SharedEntities.RiskRatingsResearch;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.RiskRatingResearchProfileLogic
{
    public class RiskRatingResearchProfileQuery : IRiskRatingResearchProfileQuery
    {
        private readonly ILogger logger;
        private readonly BackOfficeAppSettings backOfficeAppSettings;
        private readonly RiskRatingsDataProvider.RiskRatingsDataProvider riskResearchDataProvider;

        public RiskRatingResearchProfileQuery(
            RiskRatingsDataProvider.RiskRatingsDataProvider riskResearchDataProvider, 
            BackOfficeAppSettings backOfficeAppSettings, 
            ILogger logger)
        {
            this.riskResearchDataProvider = riskResearchDataProvider;
            this.logger = logger;
            this.backOfficeAppSettings = backOfficeAppSettings;

            logger.Log($"\nWorking with HBase Thrift server {backOfficeAppSettings.ThriftServer} and Phoenix server {backOfficeAppSettings.PhoenixServer}");
        }

        public IList<ComprehensiveRiskRatingResearchProfile> Get(IList<Guid> companiesIds)
        {
            var callerMethod = new StackFrame(1).GetMethod().Name;

            var stopWatch = Stopwatch.StartNew();

            logger.Log($"Start getting data from the cluster for {callerMethod}: requested {companiesIds.Count} companies");

            if (companiesIds.Count == 0) return null;

            var riskRatingResearchProfiles = Retry.Do(() => riskResearchDataProvider.GetComprehensiveRiskRatingsProfileByCompanyIds(companiesIds.AsEnumerable()).ToList(),
                                                 backOfficeAppSettings.WaitRetryDuration,
                                                 logger,
                                                 backOfficeAppSettings.RetryNumberOfTimes);

            var riskRatingsResearchProfiles = riskRatingResearchProfiles.SelectMany(rp => rp.MaterialEsgIssues).Count();

            logger.Log($"Finished getting data from the cluster for {callerMethod}: requested {companiesIds.Count()} companies, " +
                       $"received {riskRatingResearchProfiles.Count} companies" +
                       $" and {riskRatingsResearchProfiles} {typeof(MaterialEsgIssue).Name} MaterialEsgIssues" +
                       $" ( duration {stopWatch.Elapsed} )");

            return riskRatingResearchProfiles;
        }
    }
}
